package com.ruoyi.project.module.products.service;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ImportExcelConstants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ImportExcelUtil;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.project.common.domain.ErrorCommon;
import com.ruoyi.project.module.ordersDetail.domain.OrdersDetail;
import com.ruoyi.project.module.ordersDetail.mapper.OrdersDetailMapper;
import com.ruoyi.project.module.productsUpload.domain.ProductsUpload;
import com.ruoyi.project.module.productsUpload.service.IProductsUploadService;
import com.ruoyi.project.module.purchases.domain.Purchases;
import com.ruoyi.project.module.purchases.mapper.PurchasesMapper;
import com.ruoyi.project.system.dict.service.IDictDataService;
import com.ruoyi.project.system.user.domain.User;
import org.apache.regexp.RE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import com.ruoyi.project.module.products.mapper.ProductsMapper;
import com.ruoyi.project.module.products.domain.Products;
import com.ruoyi.common.support.Convert;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;

/**
 * 商品以及库存 服务层实现
 *
 * @author lcx
 * @date 2018-08-15
 */
@Service
public class ProductsServiceImpl implements IProductsService {
    @Autowired
    private ProductsMapper productsMapper;
    @Autowired
    private IDictDataService dictDataService;
    @Autowired
    private IProductsUploadService productsUploadService;
    @Resource(name = "transactionManager")
    private DataSourceTransactionManager transactionManager;
    @Autowired
    private OrdersDetailMapper ordersDetailMapper;
    @Autowired
    private PurchasesMapper purchasesMapper;


    /**
     * 查询商品以及库存信息
     *
     * @param id 商品以及库存ID
     * @return 商品以及库存信息
     */
    @Override
    public Products selectProductsById(String id) {
        return productsMapper.selectProductsById(id);
    }

    /**
     * 查询商品以及库存列表
     *
     * @param products 商品以及库存信息
     * @return 商品以及库存集合
     */
    @Override
    public List<Products> selectProductsList(Products products) {
        if (StringUtils.isNotEmpty(products.getSearchValue())) {

            String[] searchRow = {
                    "p.productName",
                    "p.mainSKU",
                    "p.unionSKU",
                    "p.EAN"
            };

            return productsMapper.selectProductsListAsSearchRow(products, searchRow);
        }
        //默认搜索
        return productsMapper.selectProductsList(products);

    }

    /*计算合计*/
    @Override
    public List<Products> selectSumCountProductsList(Products products) {
        if (StringUtils.isNotEmpty(products.getSearchValue())) {

            String[] searchRow = {
                    "p.productName",
                    "p.mainSKU",
                    "p.unionSKU",
            };

            return productsMapper.selectProductsListAsSearchSumRow(products, searchRow);
        }
        //默认搜索
        return productsMapper.selectProductsListAsSum(products);
    }

    /*扫码发货校验接口*/
    @Override
    public List<String> updateProductsAsSweepCodeStockTaking(String[] stockIds) {


        List<String> reList = new ArrayList<>();
        List<String> temList = new ArrayList<>();

        /*筛选是否有单号错误的记录*/
        for (String stid : stockIds) {
            Purchases purchases = purchasesMapper.selectPurchasesBySweepCodeId(stid.trim());
            if (purchases == null) {
                reList.add(stid);
            } else {
                temList.add(purchases.getProductId());
            }
        }
        /*如果都存在则插入*/
        if (reList.size() == 0) {
            for (String stid : stockIds) {
                uploadProductAsidAndType(stid, 1, "ShareQuantity");
            }
        }

        return reList;
    }

    /**
     * 新增商品以及库存
     *
     * @param products 商品以及库存信息
     * @return 结果
     */
    @Override
    public int insertProducts(Products products) {
        return productsMapper.insertProducts(products);
    }

    /**
     * 修改商品以及库存
     *
     * @param products 商品以及库存信息
     * @return 结果
     */
    @Override
    public int updateProducts(Products products) {
        return productsMapper.updateProducts(products);
    }

    /**
     * 删除商品以及库存对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteProductsByIds(String ids) {
        return productsMapper.deleteProductsByIds(Convert.toStrArray(ids));
    }

    /**
     * @Author lcx
     * @Date 2018/8/25 9:48
     * 批量上传商品信息
     */
    @Override
    public List<ErrorCommon> uploadProduct(List<ProductsUpload> phList, String download, String bz) {

        //错误返回对象
        List<ErrorCommon> errorList = new ArrayList();
        //导入的商品集合
        List<Products> productsList = new ArrayList();
        //导入上传历史表的内容
        List<ProductsUpload> productsUploadList = new ArrayList();
        try {

            for (ProductsUpload productsUpload : phList) {
                File file = new File(download + productsUpload.getFileUrl());  //根据文件路径获得File文件

                //获取xls数据
                List<List<Object>> temList_tem = ImportExcelUtil.importExcel(file);

                List<List<Object>> temList = new ArrayList();

                //获取xls 的图片
                List<Object> temList1 = ImportExcelUtil.getImage(file);

                //获取稳定排序
                List<Integer> rowList = ImportExcelUtil.getImageAsRowNum(file);

                /*System.out.printf(temList1.toString());*/
                temList.add(temList_tem.get(0));
                for (int row : rowList) {
                    /* System.out.println("test:"+row);*/
                    temList.add(temList_tem.get(row));
                }
                /*System.out.printf(temList.toString());*/

                //如果获取图片个数与xls商品个数不一致则不导入
                if (temList1.size() != temList.size() - 1) {
                    reErrorRL(errorList, 0, 0, ImportExcelConstants.IMAGE_NUM_ERROR);
                } else if (temList1.size() == 0) {
                    reErrorRL(errorList, 0, 0, ImportExcelConstants.IMAGE_NUM_ERROR);
                } else {

                    for (int low = 1; low < temList.size(); low++) {
                        //获取行
                        List<Object> row = temList.get(low);

                        String product_class = dictDataService.selectDictValue(ImportExcelConstants.ERP_PRODUCT_CLASS, String.valueOf(row.get(0)));
                        //判断商品分类是否存在
                        if (StringUtils.isNull(product_class)) {
                            reErrorRL(errorList, low, 0, row.get(0) + ImportExcelConstants.NO_EXIST);
                        }
                        //查询商品类型
                        String product_type = dictDataService.selectDictValue(ImportExcelConstants.ERP_PRODUCT_TYPE, String.valueOf(row.get(1)));
                        //判断商品类型是否存在
                        if (StringUtils.isNull(product_type)) {
                            reErrorRL(errorList, low, 1, row.get(1) + ImportExcelConstants.NO_EXIST);
                        }
                        //查询商品主SKU
                        Products ProductsTemp = productsMapper.selectProductsByMainSKU(String.valueOf(row.get(2)));
                        //判断商品主SKU是否存在
                        if (ProductsTemp != null) {
                            reErrorRL(errorList, low, 2, row.get(2) + ImportExcelConstants.REPEAT);
                        }
                        //产品名称为空
                        if ("".equals(row.get(4))) {
                            reErrorRL(errorList, low, 4, row.get(4) + ImportExcelConstants.IS_NULL);
                        }
                        //SIZE为空
                        if ("".equals(row.get(5))) {
                            reErrorRL(errorList, low, 5, row.get(5) + ImportExcelConstants.IS_NULL);
                        }
                        //放入图片文件名
                        String imgFileName = (String) temList1.get(low - 1);
                        //添加需要导入的数据
                        addProduct(product_class, product_type, imgFileName, productsList, bz, row, low);


                    }
                }


                //添加上传历史信息集合
                addProductsUpload(productsUpload.getFileUrl(), temList1.size(), bz, productsUploadList);

            }

            //有错误信息则不插入
            if (errorList.size() == 0) {
                //插入数据库
                for (Products productsTem : productsList) {
                    productsMapper.insertProducts(productsTem);
                }
                //插入数据库
                for (ProductsUpload productsUploadTem : productsUploadList) {
                    productsUploadService.insertProductsUpload(productsUploadTem);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return errorList;

    }

    /**
     * @Author lcx
     * @Date 2018/8/31 17:26
     * 校验主sku
     */
    @Override
    public String selectProductsFlagByMainSKU(String mainSKU) {
        //查询商品主SKU
        Products ProductsTemp = productsMapper.selectProductsByMainSKU(mainSKU);
        //判断商品主SKU是否存在
        if (ProductsTemp != null) {
            return Constants.SUCCESS;
        }
        return Constants.FAIL;
    }

    @Override
    public Products selectProductsByMainSKU(String mainSKU) {
        return productsMapper.selectProductsByMainSKU(mainSKU);
    }

    /**
     * @Author lcx
     * @Date 2018/9/15 15:47
     * 更新库存信息
     */
    @Override
    public List<Integer> uploadProductAsMainSkuAndType(List<String> mainSkuList, List<Integer> numList, String type) {
        int i = 0;
        int re_tem = 0;
        ArrayList<Integer> notExistGoods = new ArrayList<Integer>();

        /*//---------设置手动提交事务----------------
        DefaultTransactionDefinition transDefinition = new DefaultTransactionDefinition();
        //开启新事物
        transDefinition.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus transStatus = transactionManager.getTransaction(transDefinition);*/

        for (int j = 0; j < numList.size(); j++) {
            Integer num = 0;
            try {
                Products ProductsTemp = productsMapper.selectProductsByMainSKU(mainSkuList.get(j));

                if (ProductsTemp == null) {//商品不存在时跳出此次循环（依然发货成功）
                    notExistGoods.add(j + 1);
                    continue;
//                    transactionManager.rollback(transStatus);
//                    return Constants.GOODS_NOT_EXIST;
                }

                if (ProductsTemp.getOnhand() > numList.get(j)) {
                    OrdersDetail ordersDetail = new OrdersDetail();
                    ordersDetail.setOrderStatus("10708");
                    ordersDetailMapper.updateOrdersDetailBySku();
                }

                Class<? extends Products> productsTempClass = ProductsTemp.getClass();

                // 调用get方法
                Method method = productsTempClass.getMethod("get" + type);

                Method method1 = productsTempClass.getMethod("set" + type, Integer.class);

                // 得到值
                Object invoke = method.invoke(ProductsTemp);
                if (invoke == null) {
                    num = numList.get(i);
                } else {
                    num = (int) invoke + numList.get(i);
                }
                //System.err.printf("getPurchaseQuantity1"+String.valueOf(ProductsTemp.getPurchaseQuantity()));

                method1.invoke(ProductsTemp, num);

                //System.err.printf("getPurchaseQuantity"+String.valueOf(ProductsTemp.getPurchaseQuantity()));
                re_tem += productsMapper.updateProducts(ProductsTemp);

                i++;
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
//        transactionManager.commit(transStatus);//提交事务

        return notExistGoods;
    }

    /**
     * @Author lcx
     * @Date 2018/9/23 15:28
     * 修改库存根据id
     */
    @Override
    public int uploadProductAsidAndType(String id, Integer nums, String type) {
        int re_tem = 0;

        //---------设置手动提交事务----------------
        DefaultTransactionDefinition transDefinition = new DefaultTransactionDefinition();
        //开启新事物
        transDefinition.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus transStatus = transactionManager.getTransaction(transDefinition);

        Integer num = 0;
        try {
            Products ProductsTemp = productsMapper.selectProductsById(id);

            if (ProductsTemp == null) {//商品不存在时回滚事务
                transactionManager.rollback(transStatus);
                return Constants.GOODS_NOT_EXIST;
            }
            Class<? extends Products> productsTempClass = ProductsTemp.getClass();

            // 调用get方法
            Method method = productsTempClass.getMethod("get" + type);

            Method method1 = productsTempClass.getMethod("set" + type, Integer.class);

            // 得到值
            Object invoke = method.invoke(ProductsTemp);
            if (invoke == null) {
                num = nums;
            } else {
                num = (int) invoke + nums;
            }
            //System.err.printf("getPurchaseQuantity1"+String.valueOf(ProductsTemp.getPurchaseQuantity()));

            method1.invoke(ProductsTemp, num);


            //System.err.printf("getPurchaseQuantity"+String.valueOf(ProductsTemp.getPurchaseQuantity()));
            re_tem += productsMapper.updateProducts(ProductsTemp);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        transactionManager.commit(transStatus);

        return re_tem;
    }

    /**
     * @Author lcx
     * @Date 2018/8/25 11:00
     * 添加错误信息
     */
    private List<ErrorCommon> reErrorRL(List<ErrorCommon> errorLists, int low, int row, Object error) {
        ErrorCommon errorCommon = new ErrorCommon();

        errorCommon.setLow(low + 1);
        errorCommon.setRow(row + 1);
        errorCommon.setErrorValue(String.valueOf(error));

        errorLists.add(errorCommon);

        return errorLists;
    }

    /**
     * @Author lcx
     * @Date 2018/8/25 11:36
     * 添加商品
     */

    private List<Products> addProduct(String product_class, String product_type, String imgFileName,
                                      List<Products> productsList, String bz, List row, int low) {

        User user = ShiroUtils.getUser();

        Products products = new Products();
        products.setProductClass(product_class);
        products.setProductType(product_type);
        products.setMainSKU(String.valueOf(row.get(2)));
        products.setUnionSKU(String.valueOf(row.get(3)));
        products.setProductName(String.valueOf(row.get(4)));
        products.setSize(String.valueOf(row.get(5)));
        products.setEAN(String.valueOf(row.get(6)));
        products.setBz(String.valueOf(row.get(7)));
        products.setLine_num(low);

        /*非xls内容*/
        products.setId(UUID.randomUUID().toString());
        products.setCreatorId(String.valueOf(user.getUserId()));
        products.setCompanyId(String.valueOf(user.getDeptId()));

        //插入xls图片路径
        products.setPicUrl(imgFileName);

        productsList.add(products);

        return productsList;
    }

    /**
     * @Author lcx
     * @Date 2018/8/31 8:55
     * 添加上传信息
     */
    private List<ProductsUpload> addProductsUpload(String urlName, int productNum, String bz,
                                                   List<ProductsUpload> addProductsUpload) {


        ProductsUpload productsUpload = new ProductsUpload();
        productsUpload.setFileUrl(urlName);
        productsUpload.setCounts(String.valueOf(productNum));
        productsUpload.setBz(bz);

        //添加其他信息

        User user = ShiroUtils.getUser();
        productsUpload.setCreateId(String.valueOf(user.getUserId()));
        productsUpload.setCompanyId(String.valueOf(user.getDeptId()));

        addProductsUpload.add(productsUpload);

        return addProductsUpload;

    }
}
